package cn.kgc.commons.advice;

import cn.kgc.base.entity.SysDict;
import cn.kgc.base.entity.SysDictItem;
import cn.kgc.base.mapper.SysDictItemMapper;
import cn.kgc.base.mapper.SysDictMapper;
import cn.kgc.commons.annotation.Dict;
import cn.kgc.commons.constant.SysDictItemStatus;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.ObjectMapper;
import jdk.nashorn.internal.ir.annotations.Reference;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>翻译返回值的常量</p>
 *SysDict表，从常量表中将用户返回的sex为1的值
 * @author 李孟鸠
 * @Date: 2022年12月01日10:28
 */
@Aspect
@Component
@Slf4j
public class AutoDictAdvice {

    @Resource
    private SysDictMapper sysDictMapper;

    @Resource
    private SysDictItemMapper sysDictItemMapper;

    @Pointcut("@annotation(cn.kgc.commons.annotation.AutoDict)")
    public void autoDictPointcut(){}

    @Around("autoDictPointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object result = proceedingJoinPoint.proceed();//执行目标方法

        result=parseResultDictText(result);
        return result;
    }

    /**
     * 解析目标返回值
     * @param result
     * @return
     */
    private Object parseResultDictText(Object result) throws Exception {
       if (result instanceof IPage){  //目标方法返回的是分页数据
           ObjectMapper objectMapper=new ObjectMapper(); //jackson
            //获得分页数据
           List<Object> objectList = ((IPage<Object>) result).getRecords();
           //存储处理后的数据 JSONObject可以添加属性
           List<JSONObject>resultList=new ArrayList<>();

           for (Object o : objectList) {
               String json = objectMapper.writeValueAsString(o); //将对象转换为json字符串
               //将原有的每条数据转为JSONObject类型的 JSONObject对象中的属性的值
               //来自于原有的每条数据（可以很方便的给JSONObject对象添加属性）
               JSONObject jsonObject =
                       JSONObject.parseObject(json, Feature.OrderedField);
              //原有的属性上是否含有@Dict注解，如果属性上含有@Dict注解，需要进行转换
               Field[] fields = o.getClass().getDeclaredFields(); //获得原有的每条数据的属性
               for (Field temp : fields) {
                   //属性的访问修饰符是私有的，通过该方法，可以访问私有的属性
                   temp.setAccessible(true); //设置属性可访问
                   //判断属性上是否含有@Dict注解
                   if (temp.isAnnotationPresent(Dict.class)){
                       Dict dict = temp.getAnnotation(Dict.class); //获得@Dict注解
                       String dictCode = dict.dictCode(); //获得字典编码
                       String fieldName = temp.getName();// 获得属性的名字
//                       Object fileValue2 = temp.get(o);  也是获得属性的值  是通过fastJson转换后的值
                       Object fileValue =  jsonObject.get(fieldName);
                       //根据字典编码查询字典（sys_dict）
                       LambdaQueryWrapper<SysDict>lambdaQueryWrapper=new LambdaQueryWrapper<>();
                       lambdaQueryWrapper.eq(SysDict::getDictCode,dictCode);
                       SysDict sysDict = sysDictMapper.selectOne(lambdaQueryWrapper);
                       if (sysDict!=null){ //根据编码查询到了字典，再往下查询
                           Long id = sysDict.getId();
                           LambdaQueryWrapper<SysDictItem>queryWrapper=
                                   new LambdaQueryWrapper<>();
                           queryWrapper.eq(SysDictItem::getDictId,id);
                           queryWrapper.eq(SysDictItem::getItemValue,fileValue);
                           queryWrapper.eq(SysDictItem::getStatus, SysDictItemStatus.ENABLE.getStatus());
                           SysDictItem sysDictItem = sysDictItemMapper.selectOne(queryWrapper);
                           if (sysDictItem!=null){
                               //根据字典编码和属性值，查询到了需要字典项的内容
                               String itemText = sysDictItem.getItemText(); //新的属性值
                               fieldName=fieldName+"_txt"; //新的属性名
                               jsonObject.put(fieldName,itemText); //给JSONObject对象添加属性

                           }

                       }
                   }
               }
               //获得每条数据，每条数据的属性上是否有@Dict注解，如果有注解
                //给属性后面添加一个新的属性，新的属性的名字是原有属性名+"_txt"后缀
               //属性的值翻译后的值（根据原有的属性名和字典编码从数据字典中查询出来的值）
               //将处理后的新的数据放到分页的集合中。

               resultList.add(jsonObject);

           }

           ((IPage) result).setRecords(resultList);
       }

       return result;
    }
}
